package com.itheima.health.service.impl;

import com.itheima.health.common.MessageConst;
import com.itheima.health.common.RedisConst;
import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.OrdersettingDao;
import com.itheima.health.exception.BusinessRuntimeException;
import com.itheima.health.pojo.dto.SmsLoginDTO;
import com.itheima.health.pojo.dto.SubmitDTO;
import com.itheima.health.pojo.entity.Member;
import com.itheima.health.pojo.entity.Order;
import com.itheima.health.pojo.vo.OrderInfoVO;
import com.itheima.health.service.MobileService;
import com.itheima.health.utils.AliyunSmsTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@Slf4j
public class MobileServiceImpl implements MobileService {

    //类型为：登录
    private static final String TYPE_0 =  "MOBILE_SIGNIN";
    //类型为：预约
    private static final String TYPE_1 =  "ORDER";


    @Autowired
    private AliyunSmsTemplate aliyunSmsTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private OrderDao orderDao;


    @Autowired
    private MemberDao memberDao;


    @Autowired
    private OrdersettingDao ordersettingDao;


    /**
     * 获取验证码
     * @param type
     * @param telephone
     */
    @Override
    public void getValidateCode(String type, String telephone) {

        //MOBILE_SIGNIN为登录场景
        //ORDER为预约场景
        //获取生成的验证码
        String code = aliyunSmsTemplate.sendSms(telephone);
        //拼接后以手机号+类型为主键
        String key = type+telephone;
        //验证码前缀＋验证码为值
        String value = RedisConst.VALIDATE_CODE_PREFIX+code;
        //存入redis
        try {
            log.info("key:{},value:{}",key,value);
            redisTemplate.opsForValue().set(key,value);
        }catch (Exception e){
            throw new BusinessRuntimeException("插入验证码到redis失败");
        }


    }


    /**
     *
     * @param type 0为登录，1为预定
     * @param telephone
     * @param validateCode
     * @return
     */
    public Boolean checkValidateCode(Integer type,String telephone,String validateCode){

        String key = null;

        //判断类型拼接key
        if (type == 0){
            key = TYPE_0 + telephone;
        }
        else if (type == 1){
            key = TYPE_1 + telephone;
        }
        else {
            throw new BusinessRuntimeException( type + "为无效类型");
        }

        //
        String value = ((String) redisTemplate.opsForValue().get(key)).split(":")[1];
        if (value == null || !value.equals(validateCode)){
            return true;
        }
        else {
            return false;
        }

    }


    /**
     * 用户手机验证码登录
     * @param dto
     */
    @Override
    public Boolean smsLogin(SmsLoginDTO dto) {

        //redis中没有数据或者验证码不匹配则失败
        if (checkValidateCode(0,dto.getTelephone(),dto.getValidateCode())){
            return false;
        }
        return true;
    }


    /**
     * 提交预约
     * @param submitDTO
     * @return
     */
    @Transactional
    @Override
    public Order submit(SubmitDTO submitDTO) {
        //校验验证码
        if (checkValidateCode(1,submitDTO.getTelephone(),submitDTO.getValidateCode())){
            throw new BusinessRuntimeException(MessageConst.VALIDATECODE_ERROR);
        }
        //获取会员信息
        Member member = memberDao.searchMemberByPhoneNumber(submitDTO.getTelephone());
        if (member == null){
            member = new Member();
            BeanUtils.copyProperties(submitDTO,member);
            member.setPhoneNumber(submitDTO.getTelephone());
            member.setRegTime(new Date());
            memberDao.insertMember(member);
        }
        //查询会员是否在该天已经预约了
        Integer order = orderDao.searchOrderByMemberIdAndOrderDate(member.getId(), submitDTO.getOrderDate());
        if (order > 0){
            throw new BusinessRuntimeException(MessageConst.HAS_ORDERED);
        }
        //查询是否预约已满
        Integer number = orderDao.searchOrderByMemberIdAndOrderDate(null,submitDTO.getOrderDate());
        Integer maxNumber = ordersettingDao.searchOrdersettingNumber(submitDTO.getOrderDate());
        if(number >= maxNumber){
            throw new BusinessRuntimeException(MessageConst.ORDER_FULL);
        }

        //封装预约信息
        Order newOrder = Order.builder().
                memberId(member.getId()).
                orderDate(submitDTO.getOrderDate()).
                orderType("微信预约").
                orderStatus("未到诊").
                setmealId(submitDTO.getSetmealId()).build();
        //插入到数据库中的预约表
        orderDao.insertOrder(newOrder);

        //响应给前端
        return newOrder;

    }



    /**
     * 预约成功后的预约数据显示
     * @param id
     * @return
     */
    @Override
    public OrderInfoVO findOrderById(Integer id) {
        OrderInfoVO vo = orderDao.findOrderInfoById(id);
        return vo;
    }
}
